# -*- coding: utf-8 -*-
"""
---------------------------------------
@File    : proxy_check.py
@Author  : liyunhui
@Date    : 2024/9/14 下午2:59 
@explain : IP状态检测,
---------------------------------------
"""
import requests
from config import config
from methods.adsl_call import server_dial
from methods.redis_connect import get_redis_cli


class IpStatusCheck:

    def __init__(self, logging):
        self.logging = logging
        self.redis_cli = get_redis_cli()
        self.total_ip_key = config.ip_pool_total_ip
        self.use_ip_key = config.use_ips
        self.proxy_port = config.proxy_port

    def get_total_ips(self):
        """
        获取全部代理云节点信息
        :return:
        """
        # 获取所有符合通配符的键
        keys = self.redis_cli.keys(f"{self.total_ip_key}:*")
        # 创建字典来存储数据
        ip_data_dict = {}
        # 遍历每一个符合条件的 key
        for key in keys:
            # 获取内网 IP
            intranet_ip = key.split(":")[-1]
            # 获取 Redis 哈希结构下的所有 field-value 数据
            hash_data = self.redis_cli.hgetall(key)
            # 将内网 IP 和其对应的数据存入字典
            ip_data_dict[intranet_ip] = hash_data
        return ip_data_dict

    def get_use_ip(self, intranet_ip):
        """
        根据内网IP去查询对应节点的代理IP
        :param intranet_ip:
        :return:
        """
        key = self.use_ip_key + f":{intranet_ip}"
        value = self.redis_cli.hgetall(key)
        if value:
            return value
        else:
            return None

    def ip_test(self, public_ip, is_domestic):
        """
        测试该公网IP代理是否可用
        :param public_ip:
        :param is_domestic: 是否是国内
        :return:
        """
        test_url = "https://www.baidu.com/" if is_domestic else "https://www.google.com/"
        proxy_url = f'http://{public_ip}:{self.proxy_port}'
        proxies = {
            'http': proxy_url,
            'https': proxy_url,
        }
        try:
            response = requests.get(test_url, proxies=proxies, timeout=30)
            if response.status_code == 200:
                self.logging.info(f"代理有效: {public_ip}")
                return True
            else:
                self.logging.info(f"代理失效: {public_ip}")
                return False
        except Exception as e:
            self.logging.error(f"代理失效，访问异常: {public_ip}")
            return False

    def handler(self):
        # 1、先获取所有的IP
        total_ips_info = self.get_total_ips()
        for intranet_ip, server_info in total_ips_info.items():
            # 获取对应云服务器是否有可用的代理
            proxy_info = self.get_use_ip(intranet_ip=intranet_ip)
            if proxy_info is None:
                # 发送拨号命令重新拨号
                self.logging.info(f"云主机内网IP: {intranet_ip} --- 将重启拨号服务！")
                server_dial(
                    server_info=server_info,
                    intranet_ip=intranet_ip,
                    logging=self.logging
                )
            else:
                public_ip = proxy_info.get("public_ip")
                is_domestic = eval(server_info.get("is_domestic"))
                # 检测该代理是否有效
                ip_status = self.ip_test(public_ip, is_domestic)
                if ip_status:
                    # IP有效，跳过
                    self.logging.info(f"云主机内网IP: {intranet_ip} --- 代理: {public_ip} 有效！")
                    self.logging.info(f"")
                else:
                    # 重新拨号
                    self.logging.info(f"云主机内网IP: {intranet_ip} --- 代理: {public_ip} 无效将重新拨号！")
                    server_dial(
                        server_info=server_info,
                        intranet_ip=intranet_ip,
                        logging=self.logging
                    )
